home *** CD-ROM | disk | FTP | other *** search
- /* SampleStorageDisplay.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "SampleStorageDisplay.h"
- #include "Memory.h"
- #include "DataMunging.h"
- #include "Scrap.h"
- #include "Files.h"
-
-
- #define MAGICSCRAPSTRING ("\xff\x00\x1f\xfe SampleStorageScrap")
-
- typedef struct
- {
- char MagicString[sizeof(MAGICSCRAPSTRING)];
- NumBitsType NumberOfBits;
- NumChannelsType NumberOfChannels;
- long NumberOfBytes;
- } SampleClipboardRec;
-
-
- struct SampleStorageDisplayRec
- {
- NumBitsType NumberOfBits;
- NumChannelsType MonoStereo;
- largefixedsigned* Buffer;
- MyBoolean DataHasChanged;
-
- MyBoolean UndoFileIsValid;
- FileType* TheUndoFile;
- FileSpec* TheUndoFileLocation;
- };
-
-
- /* create a zero-length sample storage object */
- SampleStorageDisplayRec* NewSampleStorageDisplayEmpty(NumBitsType NumBits,
- NumChannelsType NumChannels)
- {
- SampleStorageDisplayRec* Storage;
-
- ERROR((NumBits != eSample16bit) && (NumBits != eSample8bit),
- PRERR(ForceAbort,"NewSampleStorageDisplayEmpty: invalid value for NewNumBits"));
- ERROR((NumChannels != eSampleMono) && (NumChannels != eSampleStereo),
- PRERR(ForceAbort,"NewSampleStorageDisplayEmpty: invalid number of channels"));
- Storage = (SampleStorageDisplayRec*)AllocPtrCanFail(
- sizeof(SampleStorageDisplayRec),"SampleStorageDisplayRec");
- if (Storage == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- Storage->Buffer = (largefixedsigned*)AllocPtrCanFail(0,"SampleDataArray");
- if (Storage->Buffer == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)Storage);
- goto FailurePoint1;
- }
- Storage->NumberOfBits = NumBits;
- Storage->MonoStereo = NumChannels;
- Storage->DataHasChanged = False;
- Storage->UndoFileIsValid = False;
- return Storage;
- }
-
-
- /* create a zero-length sample storage object */
- SampleStorageDisplayRec* NewSampleStorageDisplayData(NumBitsType NumBits,
- NumChannelsType NumChannels, largefixedsigned* DataBlock)
- {
- SampleStorageDisplayRec* Storage;
-
- ERROR((NumBits != eSample16bit) && (NumBits != eSample8bit),
- PRERR(ForceAbort,"NewSampleStorageDisplayData: invalid value for NewNumBits"));
- ERROR((NumChannels != eSampleMono) && (NumChannels != eSampleStereo),
- PRERR(ForceAbort,"NewSampleStorageDisplayData: invalid number of channels"));
- CheckPtrExistence(DataBlock);
- Storage = (SampleStorageDisplayRec*)AllocPtrCanFail(
- sizeof(SampleStorageDisplayRec),"SampleStorageDisplayRec");
- if (Storage == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- Storage->Buffer = DataBlock;
- SetTag(DataBlock,"SampleDataArray");
- ERROR((NumChannels == eSampleStereo) && ((PtrSize((char*)DataBlock)
- % (2 * sizeof(largefixedsigned))) != 0),PRERR(ForceAbort,
- "NewSampleStorageDisplayData: stereo sample not an even number of elements"));
- Storage->NumberOfBits = NumBits;
- Storage->MonoStereo = NumChannels;
- Storage->DataHasChanged = False;
- Storage->UndoFileIsValid = False;
- return Storage;
- }
-
-
- /* dispose of a sample storage object */
- void DisposeSampleStorageDisplay(SampleStorageDisplayRec* Storage)
- {
- CheckPtrExistence(Storage);
- SampleStorageDisplayFlushUndo(Storage);
- ReleasePtr((char*)Storage->Buffer);
- ReleasePtr((char*)Storage);
- }
-
-
- /* get the number of bits being represented in this sample */
- NumBitsType GetSampleStorageDisplayNumBits(
- SampleStorageDisplayRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->NumberOfBits;
- }
-
-
- /* get the number of channels being represented in this sample */
- NumChannelsType GetSampleStorageDisplayNumChannels(
- SampleStorageDisplayRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->MonoStereo;
- }
-
-
- /* get the number of frames stored in this object */
- long GetSampleStorageDisplayNumFrames(
- SampleStorageDisplayRec* Storage)
- {
- long TheLengthThang;
-
- CheckPtrExistence(Storage);
- TheLengthThang = PtrSize((char*)Storage->Buffer);
- TheLengthThang = TheLengthThang / sizeof(largefixedsigned);
- if (Storage->MonoStereo == eSampleStereo)
- {
- TheLengthThang = TheLengthThang / 2;
- }
- return TheLengthThang;
- }
-
-
- /* get a value from in the array */
- largefixedsigned GetSampleStorageDisplayValue(SampleStorageDisplayRec* Storage,
- long Index, ChannelType WhichChannel)
- {
- largefixedsigned ReturnValue;
-
- CheckPtrExistence(Storage);
- ERROR((Index < 0) || (Index >= GetSampleStorageDisplayNumFrames(Storage)),
- PRERR(ForceAbort,"GetSampleStorageDisplayValue: index out of range"));
- switch (Storage->MonoStereo)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageDisplayValue: bad internal number of channels"));
- break;
- case eSampleStereo:
- switch (WhichChannel)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageDisplayValue: bad channel selector"));
- break;
- case eLeftChannel:
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[Index * 2]),
- sizeof(largefixedsigned));
- ReturnValue = Storage->Buffer[Index * 2];
- break;
- case eRightChannel:
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[(Index * 2) + 1]),
- sizeof(largefixedsigned));
- ReturnValue = Storage->Buffer[(Index * 2) + 1];
- break;
- }
- break;
- case eSampleMono:
- switch (WhichChannel)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageDisplayValue: bad channel selector"));
- break;
- case eMonoChannel:
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[Index]),
- sizeof(largefixedsigned));
- ReturnValue = Storage->Buffer[Index];
- break;
- }
- break;
- }
- return ReturnValue;
- }
-
-
- /* find out if the array has been changed since last being saved */
- MyBoolean DoesSampleStorageDisplayNeedToBeSaved(
- SampleStorageDisplayRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->DataHasChanged;
- }
-
-
- /* change the number of bits being used to store the data */
- void SetSampleStorageDisplayNumBits(
- SampleStorageDisplayRec* Storage, NumBitsType NewNumBits)
- {
- CheckPtrExistence(Storage);
- ERROR((NewNumBits != eSample16bit) && (NewNumBits != eSample8bit),
- PRERR(ForceAbort,"SetSampleStorageDisplayNumBits: invalid value for NewNumBits"));
- Storage->NumberOfBits = NewNumBits;
- Storage->DataHasChanged = True;
- }
-
-
- /* change the number of channels being stored in the array */
- MyBoolean SetSampleStorageDisplayNumChannels(
- SampleStorageDisplayRec* Storage,
- NumChannelsType NewNumChannels)
- {
- CheckPtrExistence(Storage);
- ERROR((NewNumChannels != eSampleMono) && (NewNumChannels != eSampleStereo),
- PRERR(ForceAbort,"SetSampleStorageDisplayNumChannels: invalid number of channels"));
- if (Storage->MonoStereo != NewNumChannels)
- {
- largefixedsigned* NewBuffer;
- long Scan;
- long NumSampleFrames;
-
- NumSampleFrames = GetSampleStorageDisplayNumFrames(Storage);
- if (NewNumChannels == eSampleStereo)
- {
- /* convert mono to stereo */
- NewBuffer = (largefixedsigned*)AllocPtrCanFail(sizeof(largefixedsigned)
- * NumSampleFrames * 2,"SampleStorageDisplay Data");
- if (NewBuffer == NIL)
- {
- return False;
- }
- for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
- {
- PRNGCHK(NewBuffer,&(NewBuffer[2 * Scan + 0]),
- sizeof(NewBuffer[2 * Scan + 0]));
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[Scan]),
- sizeof(Storage->Buffer[Scan]));
- NewBuffer[2 * Scan + 0] = Storage->Buffer[Scan];
- PRNGCHK(NewBuffer,&(NewBuffer[2 * Scan + 1]),
- sizeof(NewBuffer[2 * Scan + 1]));
- NewBuffer[2 * Scan + 1] = Storage->Buffer[Scan];
- }
- }
- else
- {
- /* convert stereo to mono */
- NewBuffer = (largefixedsigned*)AllocPtrCanFail(sizeof(largefixedsigned)
- * NumSampleFrames,"SampleStorageDisplay Data");
- if (NewBuffer == NIL)
- {
- return False;
- }
- for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
- {
- PRNGCHK(NewBuffer,&(NewBuffer[Scan]),sizeof(NewBuffer[Scan]));
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[2 * Scan + 0]),
- sizeof(Storage->Buffer[2 * Scan + 0]));
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[2 * Scan + 1]),
- sizeof(Storage->Buffer[2 * Scan + 1]));
- NewBuffer[Scan] = (Storage->Buffer[2 * Scan + 0]
- + Storage->Buffer[2 * Scan + 1]) / 2;
- }
- }
- ReleasePtr((char*)Storage->Buffer);
- Storage->Buffer = NewBuffer;
- Storage->MonoStereo = NewNumChannels;
- Storage->DataHasChanged = True;
- }
- return True;
- }
-
-
- /* change the value of one of the sample points */
- void SetSampleStorageDisplayValue(SampleStorageDisplayRec* Storage,
- long Index, ChannelType WhichChannel,
- largefixedsigned NewValue)
- {
- CheckPtrExistence(Storage);
- ERROR((Index < 0) || (Index >= GetSampleStorageDisplayNumFrames(Storage)),
- PRERR(ForceAbort,"SetSampleStorageDisplayValue: index out of range"));
- Storage->DataHasChanged = True;
- switch (Storage->MonoStereo)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageDisplayValue: bad internal number of channels"));
- break;
- case eSampleStereo:
- switch (WhichChannel)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageDisplayValue: bad channel selector"));
- break;
- case eLeftChannel:
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[Index * 2]),
- sizeof(largefixedsigned));
- Storage->Buffer[Index * 2] = NewValue;
- break;
- case eRightChannel:
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[(Index * 2) + 1]),
- sizeof(largefixedsigned));
- Storage->Buffer[(Index * 2) + 1] = NewValue;
- break;
- }
- break;
- case eSampleMono:
- switch (WhichChannel)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageDisplayValue: bad channel selector"));
- break;
- case eMonoChannel:
- PRNGCHK(Storage->Buffer,&(Storage->Buffer[Index]),
- sizeof(largefixedsigned));
- Storage->Buffer[Index] = NewValue;
- break;
- }
- break;
- }
- }
-
-
- /* indicate that the object has been saved */
- void SampleStorageDisplayHasBeenSaved(
- SampleStorageDisplayRec* Storage)
- {
- CheckPtrExistence(Storage);
- Storage->DataHasChanged = False;
- }
-
-
- /* insert a bunch of zeros into the array */
- MyBoolean InsertSampleStorageDisplayArea(
- SampleStorageDisplayRec* Storage, long Index,
- long NumFramesToInsert)
- {
- long Start;
- long NumBytes;
- long OldSize;
- char* NewBuffer;
- long Scan;
-
- CheckPtrExistence(Storage);
- ERROR((Index < 0) || (Index >/*NB*/ GetSampleStorageDisplayNumFrames(Storage)),
- PRERR(ForceAbort,"InsertSampleStorageDisplayArea: index out of range"));
- ERROR(NumFramesToInsert < 0,PRERR(ForceAbort,
- "InsertSampleStorageDisplayArea: number of frames is negative"));
- Storage->DataHasChanged = True;
- OldSize = PtrSize((char*)Storage->Buffer);
- Start = Index * sizeof(largefixedsigned);
- NumBytes = NumFramesToInsert * sizeof(largefixedsigned);
- if (Storage->MonoStereo == eSampleStereo)
- {
- NumBytes *= 2;
- Start *= 2;
- }
- NewBuffer = ResizePtr((char*)Storage->Buffer,OldSize + NumBytes);
- if (NewBuffer == NIL)
- {
- return False;
- }
- Storage->Buffer = (largefixedsigned*)NewBuffer;
- PRNGCHK(NewBuffer,&(NewBuffer[Start]),OldSize - Start);
- PRNGCHK(NewBuffer,&(NewBuffer[Start + NumBytes]),OldSize - Start);
- MoveData(&(NewBuffer[Start]),&(NewBuffer[Start + NumBytes]),OldSize - Start);
- for (Scan = Start; Scan < Start + NumBytes; Scan += 1)
- {
- NewBuffer[Scan] = 0;
- }
- return True;
- }
-
-
- /* delete a range of values from the array */
- MyBoolean DeleteSampleStorageDisplayArea(
- SampleStorageDisplayRec* Storage, long Index,
- long NumFramesToDelete)
- {
- long Start;
- long NumBytes;
- long OldSize;
- char* NewBuffer;
-
- CheckPtrExistence(Storage);
- ERROR((Index < 0) || (Index + NumFramesToDelete
- > GetSampleStorageDisplayNumFrames(Storage)),
- PRERR(ForceAbort,"DeleteSampleStorageDisplayArea: index out of range"));
- ERROR(NumFramesToDelete < 0,PRERR(ForceAbort,
- "DeleteSampleStorageDisplayArea: number of frames is negative"));
- Storage->DataHasChanged = True;
- OldSize = PtrSize((char*)Storage->Buffer);
- Start = Index * sizeof(largefixedsigned);
- NumBytes = NumFramesToDelete * sizeof(largefixedsigned);
- if (Storage->MonoStereo == eSampleStereo)
- {
- NumBytes *= 2;
- Start *= 2;
- }
- NewBuffer = RemoveBlockFromBlockCopy((char*)Storage->Buffer,Start,NumBytes);
- if (NewBuffer == NIL)
- {
- return False;
- }
- ReleasePtr((char*)Storage->Buffer);
- Storage->Buffer = (largefixedsigned*)NewBuffer;
- return True;
- }
-
-
- /* extract part of the sample & create another sample record containing it */
- SampleStorageDisplayRec* ExtractSampleStorageDisplaySection(
- SampleStorageDisplayRec* Storage, long Index,
- long NumFramesToExtract)
- {
- SampleStorageDisplayRec* NewStorage;
- long Start;
- long NumBytes;
- char* NewBuffer;
-
- CheckPtrExistence(Storage);
- ERROR(((Index < 0) || (Index + NumFramesToExtract
- > GetSampleStorageDisplayNumFrames(Storage))),
- PRERR(ForceAbort,"ExtractSampleStorageDisplaySection: index out of range"));
- ERROR(NumFramesToExtract < 0,PRERR(ForceAbort,
- "ExtractSampleStorageDisplaySection: number of frames is negative"));
- Start = Index * sizeof(largefixedsigned);
- NumBytes = NumFramesToExtract * sizeof(largefixedsigned);
- if (Storage->MonoStereo == eSampleStereo)
- {
- NumBytes *= 2;
- Start *= 2;
- }
- NewBuffer = AllocPtrCanFail(NumBytes,"SampleDataBuffer");
- if (NewBuffer != NIL)
- {
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[Start]),NumBytes);
- PRNGCHK(NewBuffer,&(NewBuffer[0]),NumBytes);
- CopyData(&(((char*)Storage->Buffer)[Start]),&(NewBuffer[0]),NumBytes);
- NewStorage = NewSampleStorageDisplayData(Storage->NumberOfBits,
- Storage->MonoStereo,(largefixedsigned*)NewBuffer);
- if (NewStorage == NIL)
- {
- ReleasePtr(NewBuffer);
- NewStorage = NIL;
- }
- }
- return NewStorage;
- }
-
-
- /* insert one sample into another at a certain point */
- MyBoolean InsertSampleStorageDisplaySection(
- SampleStorageDisplayRec* Storage, long Index,
- SampleStorageDisplayRec* DataToInsert)
- {
- long NumFramesToInsert;
- NumChannelsType TheirNumChannels;
- NumChannelsType OurNumChannels;
-
- CheckPtrExistence(Storage);
- ERROR((Index < 0) || (Index > GetSampleStorageDisplayNumFrames(Storage)),
- PRERR(ForceAbort,"InsertSampleStorageDisplaySection: index is out of range"));
- Storage->DataHasChanged = True;
- NumFramesToInsert = GetSampleStorageDisplayNumFrames(DataToInsert);
- TheirNumChannels = GetSampleStorageDisplayNumChannels(DataToInsert);
- OurNumChannels = GetSampleStorageDisplayNumChannels(Storage);
- if (InsertSampleStorageDisplayArea(Storage,Index,NumFramesToInsert))
- {
- long Scan;
-
- if (TheirNumChannels == eSampleStereo)
- {
- if (OurNumChannels == eSampleStereo)
- {
- /* them stereo and us stereo */
- for (Scan = 0; Scan < NumFramesToInsert; Scan += 1)
- {
- SetSampleStorageDisplayValue(Storage,Scan + Index,eLeftChannel,
- GetSampleStorageDisplayValue(DataToInsert,Scan,eLeftChannel));
- SetSampleStorageDisplayValue(Storage,Scan + Index,eRightChannel,
- GetSampleStorageDisplayValue(DataToInsert,Scan,eRightChannel));
- }
- }
- else
- {
- /* them stereo and us mono; average their samples as we insert */
- for (Scan = 0; Scan < NumFramesToInsert; Scan += 1)
- {
- SetSampleStorageDisplayValue(Storage,Scan + Index,eMonoChannel,
- (GetSampleStorageDisplayValue(DataToInsert,Scan,eLeftChannel)
- + GetSampleStorageDisplayValue(DataToInsert,Scan,eRightChannel))
- / 2);
- }
- }
- }
- else
- {
- if (OurNumChannels == eSampleStereo)
- {
- /* them mono and us stereo; duplicate their samples */
- for (Scan = 0; Scan < NumFramesToInsert; Scan += 1)
- {
- SetSampleStorageDisplayValue(Storage,Scan + Index,eLeftChannel,
- GetSampleStorageDisplayValue(DataToInsert,Scan,eMonoChannel));
- SetSampleStorageDisplayValue(Storage,Scan + Index,eRightChannel,
- GetSampleStorageDisplayValue(DataToInsert,Scan,eMonoChannel));
- }
- }
- else
- {
- /* them mono and us mono */
- for (Scan = 0; Scan < NumFramesToInsert; Scan += 1)
- {
- SetSampleStorageDisplayValue(Storage,Scan + Index,eMonoChannel,
- GetSampleStorageDisplayValue(DataToInsert,Scan,eMonoChannel));
- }
- }
- }
- return True;
- }
- else
- {
- return False;
- }
- }
-
-
- /* dump the contents of the object and install a copy of the contents of another */
- MyBoolean SampleStorageDisplaySetContents(
- SampleStorageDisplayRec* Storage,
- SampleStorageDisplayRec* NewData)
- {
- char* Copy;
-
- CheckPtrExistence(Storage);
- CheckPtrExistence(NewData);
- Copy = CopyPtr((char*)NewData->Buffer);
- if (Copy == NIL)
- {
- return False;
- }
- ReleasePtr((char*)Storage->Buffer);
- Storage->Buffer = (largefixedsigned*)Copy;
- Storage->NumberOfBits = NewData->NumberOfBits;
- Storage->MonoStereo = NewData->MonoStereo;
- Storage->DataHasChanged = True;
- return True;
- }
-
-
- /* put the raw data for the sample onto the clipboard */
- void PutSampleStorageDisplayOnClipboard(
- SampleStorageDisplayRec* Storage)
- {
- char* Buffer;
-
- CheckPtrExistence(Storage);
- Buffer = AllocPtrCanFail(sizeof(SampleClipboardRec)
- + PtrSize((char*)Storage->Buffer),"SampleScrap");
- if (Buffer == NIL)
- {
- return;
- }
- CopyData(MAGICSCRAPSTRING,&(((SampleClipboardRec*)Buffer)->MagicString[0]),
- sizeof(MAGICSCRAPSTRING));
- ((SampleClipboardRec*)Buffer)->NumberOfBits = Storage->NumberOfBits;
- ((SampleClipboardRec*)Buffer)->NumberOfChannels = Storage->MonoStereo;
- ((SampleClipboardRec*)Buffer)->NumberOfBytes = PtrSize((char*)Storage->Buffer);
- CopyData((char*)Storage->Buffer,(char*)Buffer + sizeof(SampleClipboardRec),
- PtrSize((char*)Storage->Buffer));
- SetScrapToThis(Buffer);
- ReleasePtr(Buffer);
- }
-
-
- /* get a sample off the clipboard. returns NIL if the scrap isn't a sample */
- SampleStorageDisplayRec* GetSampleStorageDisplayFromClipboard(void)
- {
- char* Buffer;
- SampleStorageDisplayRec* Storage;
- long Scan;
- char* BufferResized;
- NumBitsType NumBits;
- NumChannelsType NumChannels;
-
- Buffer = GetCopyOfScrap();
- if (Buffer == NIL)
- {
- return NIL;
- }
- if (PtrSize(Buffer) < sizeof(SampleClipboardRec))
- {
- NotEnoughMemory:
- NotOurScrap:
- ReleasePtr(Buffer);
- return NIL;
- }
- for (Scan = 0; Scan < sizeof(MAGICSCRAPSTRING); Scan += 1)
- {
- if (MAGICSCRAPSTRING[Scan] != ((SampleClipboardRec*)Buffer)->MagicString[Scan])
- {
- goto NotOurScrap;
- }
- }
- if (sizeof(SampleClipboardRec) + ((SampleClipboardRec*)Buffer)->NumberOfBytes
- != PtrSize(Buffer))
- {
- goto NotOurScrap;
- }
- if ((((SampleClipboardRec*)Buffer)->NumberOfBits != eSample8bit)
- && (((SampleClipboardRec*)Buffer)->NumberOfBits != eSample16bit))
- {
- goto NotOurScrap;
- }
- if ((((SampleClipboardRec*)Buffer)->NumberOfChannels != eSampleMono)
- && (((SampleClipboardRec*)Buffer)->NumberOfChannels != eSampleStereo))
- {
- goto NotOurScrap;
- }
- NumBits = ((SampleClipboardRec*)Buffer)->NumberOfBits;
- NumChannels = ((SampleClipboardRec*)Buffer)->NumberOfChannels;
- MoveData(Buffer + sizeof(SampleClipboardRec),Buffer,
- PtrSize(Buffer) - sizeof(SampleClipboardRec));
- BufferResized = ResizePtr(Buffer,PtrSize(Buffer) - sizeof(SampleClipboardRec));
- if (BufferResized == NIL)
- {
- goto NotEnoughMemory;
- }
- Storage = NewSampleStorageDisplayData(NumBits,NumChannels,
- (largefixedsigned*)BufferResized);
- if (Storage == NIL)
- {
- ReleasePtr(BufferResized);
- return NIL;
- }
- return Storage;
- }
-
-
- /* get a copy of a particular channel of data from the sample */
- largefixedsigned* SampleStorageDisplayGetChannelFixed(
- SampleStorageDisplayRec* Storage, ChannelType WhichChannel)
- {
- largefixedsigned* Data;
- long Limit;
-
- CheckPtrExistence(Storage);
- Limit = GetSampleStorageDisplayNumFrames(Storage);
- Data = (largefixedsigned*)AllocPtrCanFail(sizeof(largefixedsigned)
- * Limit,"SampleFixed");
- if (Data != NIL)
- {
- long Scan;
-
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- Data[Scan] = GetSampleStorageDisplayValue(Storage,Scan,WhichChannel);
- }
- }
- return Data;
- }
-
-
- /* put a new block of data into the sample object. a copy of the block is made */
- MyBoolean SampleStorageDisplayPutMonoFixed(
- SampleStorageDisplayRec* Storage, largefixedsigned* Data)
- {
- long Difference;
- long Scan;
- long Limit;
-
- CheckPtrExistence(Storage);
- CheckPtrExistence(Data);
- ERROR(PtrSize((char*)Data) % sizeof(largefixedsigned) != 0,PRERR(ForceAbort,
- "SampleStorageDisplayPutMonoFixed: array alignment error"));
- Limit = PtrSize((char*)Data) / sizeof(largefixedsigned);
- Difference = Limit - GetSampleStorageDisplayNumFrames(Storage);
- if (Difference > 0)
- {
- /* new data is bigger, so we insert the difference */
- if (!InsertSampleStorageDisplayArea(Storage,
- GetSampleStorageDisplayNumFrames(Storage),Difference))
- {
- return False;
- }
- }
- else if (Difference < 0)
- {
- /* new data is smaller, so we delete the difference */
- Difference = - Difference;
- if (!DeleteSampleStorageDisplayArea(Storage,
- GetSampleStorageDisplayNumFrames(Storage) - Difference,Difference))
- {
- return False;
- }
- }
- /* else don't do anything */
- ERROR(GetSampleStorageDisplayNumFrames(Storage) != Limit,PRERR(ForceAbort,
- "SampleStorageDisplayPutMonoFixed: storage size inconsistency"));
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- SetSampleStorageDisplayValue(Storage,Scan,eMonoChannel,Data[Scan]);
- }
- return True;
- }
-
-
- /* put two new blocks of data into a stereo sample object. copies are made */
- MyBoolean SampleStorageDisplayPutStereoFixed(
- SampleStorageDisplayRec* Storage, largefixedsigned* Left,
- largefixedsigned* Right)
- {
- long Difference;
- long Scan;
- long Limit;
-
- CheckPtrExistence(Storage);
- ERROR(PtrSize((char*)Left) != PtrSize((char*)Right),PRERR(ForceAbort,
- "SampleStoragePutStereoFixed: Left and Right sizes are not equal"));
- ERROR(PtrSize((char*)Left) % sizeof(largefixedsigned) != 0,PRERR(ForceAbort,
- "SampleStoragePutStereoFixed: array alignment error"));
- Limit = PtrSize((char*)Left) / sizeof(largefixedsigned);
- Difference = Limit - GetSampleStorageDisplayNumFrames(Storage);
- if (Difference > 0)
- {
- /* new data is bigger, so we insert the difference */
- if (!InsertSampleStorageDisplayArea(Storage,
- GetSampleStorageDisplayNumFrames(Storage),Difference))
- {
- return False;
- }
- }
- else if (Difference < 0)
- {
- /* new data is smaller, so we delete the difference */
- Difference = - Difference;
- if (!DeleteSampleStorageDisplayArea(Storage,
- GetSampleStorageDisplayNumFrames(Storage) - Difference,Difference))
- {
- return False;
- }
- }
- /* else don't do anything */
- ERROR(GetSampleStorageDisplayNumFrames(Storage) != Limit,PRERR(ForceAbort,
- "SampleStoragePutStereoFixed: storage size inconsistency"));
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- SetSampleStorageDisplayValue(Storage,Scan,eLeftChannel,Left[Scan]);
- SetSampleStorageDisplayValue(Storage,Scan,eRightChannel,Right[Scan]);
- }
- return True;
- }
-
-
- /* flush any undo information */
- void SampleStorageDisplayFlushUndo(SampleStorageDisplayRec* Storage)
- {
- CheckPtrExistence(Storage);
- if (Storage->UndoFileIsValid)
- {
- CloseFile(Storage->TheUndoFile);
- DeleteFile(Storage->TheUndoFileLocation);
- DisposeFileSpec(Storage->TheUndoFileLocation);
- Storage->UndoFileIsValid = False;
- }
- }
-
-
- /* save the object to a temporary file so that we can undo any changes. */
- /* if it couldn't be done, then it returns False */
- MyBoolean SampleStorageDisplaySetupForUndo(SampleStorageDisplayRec* Storage)
- {
- long BufferLength;
-
- CheckPtrExistence(Storage);
- SampleStorageDisplayFlushUndo(Storage);
-
- /* try to obtain a temporary file */
- Storage->TheUndoFileLocation = NewTempFileSpec(CODE4BYTES('?','?','?','?'),
- CODE4BYTES('?','?','?','?'));
- if (Storage->TheUndoFileLocation == NIL)
- {
- /* couldn't be done */
- FailurePoint1:
- return False;
- }
-
- /* try to open it */
- if (!OpenFile(Storage->TheUndoFileLocation,&(Storage->TheUndoFile),eReadAndWrite))
- {
- FailurePoint2:
- DeleteFile(Storage->TheUndoFileLocation);
- DisposeFileSpec(Storage->TheUndoFileLocation);
- goto FailurePoint2;
- }
-
- /* save data */
- if (0 != WriteToFile(Storage->TheUndoFile,(char*)&(Storage->NumberOfBits),
- sizeof(Storage->NumberOfBits)))
- {
- FailurePoint3:
- CloseFile(Storage->TheUndoFile);
- goto FailurePoint2;
- }
- if (0 != WriteToFile(Storage->TheUndoFile,(char*)&(Storage->MonoStereo),
- sizeof(Storage->MonoStereo)))
- {
- FailurePoint4:
- goto FailurePoint3;
- }
- BufferLength = PtrSize((char*)Storage->Buffer);
- if (0 != WriteToFile(Storage->TheUndoFile,(char*)&BufferLength,sizeof(long)))
- {
- FailurePoint5:
- goto FailurePoint4;
- }
- if (0 != WriteToFile(Storage->TheUndoFile,(char*)Storage->Buffer,BufferLength))
- {
- FailurePoint6:
- goto FailurePoint5;
- }
-
- /* wow, we made it through, so we get to set this little flag thingie here! */
- Storage->UndoFileIsValid = True;
-
- return True;
- }
-
-
- /* find out if we can undo something */
- MyBoolean SampleStorageDisplayUndoAvailable(SampleStorageDisplayRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->UndoFileIsValid;
- }
-
-
- /* try to undo something. returns True if the undo data was successfully recovered. */
- /* the current state is swapped with the recovered state */
- MyBoolean SampleStorageDisplayUndo(SampleStorageDisplayRec* Storage)
- {
- MyBoolean OldUndoIsValid;
- FileType* OldUndoFile;
- FileSpec* OldUndoFileLocation;
-
- NumBitsType LocalNumberOfBits;
- NumChannelsType LocalMonoStereo;
- long NumberOfBytes;
- largefixedsigned* LocalBuffer;
-
-
- CheckPtrExistence(Storage);
- ERROR(!Storage->UndoFileIsValid,PRERR(ForceAbort,
- "SampleStorageDisplayUndo: there is no saved undo information"));
-
- /* save old undo information so we can recover stuff */
- OldUndoIsValid = Storage->UndoFileIsValid;
- OldUndoFile = Storage->TheUndoFile;
- OldUndoFileLocation = Storage->TheUndoFileLocation;
-
- /* save current state for undoing */
- Storage->UndoFileIsValid = False; /* DON'T discard previous information */
- if (!SampleStorageDisplaySetupForUndo(Storage))
- {
- /* failed -- restore state & return */
- FailurePoint1:
- Storage->UndoFileIsValid = OldUndoIsValid;
- Storage->TheUndoFile = OldUndoFile;
- Storage->TheUndoFileLocation = OldUndoFileLocation;
- return False;
- }
-
- /* now try to build new information for us */
- if (!SetFilePosition(OldUndoFile,0))
- {
- FailurePoint2:
- goto FailurePoint1;
- }
-
- /* read in cute informations */
- if (0 != ReadFromFile(OldUndoFile,(char*)&LocalNumberOfBits,sizeof(LocalNumberOfBits)))
- {
- FailurePoint3:
- goto FailurePoint2;
- }
- if (0 != ReadFromFile(OldUndoFile,(char*)&LocalMonoStereo,sizeof(LocalMonoStereo)))
- {
- FailurePoint4:
- goto FailurePoint3;
- }
- if (0 != ReadFromFile(OldUndoFile,(char*)&NumberOfBytes,sizeof(long)))
- {
- FailurePoint5:
- goto FailurePoint4;
- }
- LocalBuffer = (largefixedsigned*)AllocPtrCanFail(NumberOfBytes,"SampleDataArray");
- if (LocalBuffer == NIL)
- {
- FailurePoint6:
- goto FailurePoint5;
- }
- if (0 != ReadFromFile(OldUndoFile,(char*)LocalBuffer,NumberOfBytes))
- {
- FailurePoint7:
- ReleasePtr((char*)LocalBuffer);
- goto FailurePoint6;
- }
-
- /* now we've successfully read all of the data in. */
- /* we can replace current data with read in data & discard local undo stuff */
-
- /* dispose old undo information */
- CloseFile(OldUndoFile);
- DeleteFile(OldUndoFileLocation);
- DisposeFileSpec(OldUndoFileLocation);
-
- /* dump current information */
- Storage->NumberOfBits = LocalNumberOfBits;
- Storage->MonoStereo = LocalMonoStereo;
- ReleasePtr((char*)Storage->Buffer);
- Storage->Buffer = LocalBuffer;
-
- Storage->DataHasChanged = True;
-
- return True;
- }
-
-
- /* get the actual raw data in the channel */
- largefixedsigned* SampleStorageDisplayGetActualData(SampleStorageDisplayRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->Buffer;
- }
-